/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package deatax.network;

import deatax.GameDataController;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;

/**
 *
 * @author Pieman
 */
public class Client {

    GameDataController data;
    Socket s;
    PrintWriter output;
    BufferedReader input;
    static Client c = null;
    ArrayList<NetworkListener> listeners;

    public Client(GameDataController data) {
        this.data = data;
        listeners = new ArrayList<NetworkListener>();
        c = this;
    }

    public boolean connect(String host, int port) {

        try {
            s = new Socket(host, port);
            input = new BufferedReader(new InputStreamReader(s.getInputStream()));
            output = new PrintWriter(s.getOutputStream(), true);
            ClientThread ct = new ClientThread();
            ct.start();
            return true;
        } catch (IOException ex) {
            
        }
        return false;
    }

    public synchronized void addListener(NetworkListener listener) {
        listeners.add(listener);
    }

    public synchronized void removeListener(NetworkListener listener) {
        listeners.remove(listener);
    }

    public synchronized void clearListeners() {
        listeners.clear();
    }

    public synchronized void processListeners(int type, String[] arg) {
        ArrayList<NetworkListener> lcopy = new ArrayList<NetworkListener>();
        lcopy.addAll(listeners);

        for (NetworkListener l : lcopy) {
            l.processMessage(type, arg);
        }
    }

    public static GameDataController getData() {
        return c.getControl();
    }

    public static Client get() {
        return c;
    }

    public GameDataController getControl() {
        return data;
    }

    public synchronized void sendMessage(int message_type) {
        sendMessage(message_type, new String[]{});
    }

    public synchronized void sendMessage(int message_type, ArrayList<String> params) {
        StringBuilder sb = new StringBuilder();
        if (params != null) {
            for (String p : params) {
                sb.append(p).append(":");
            }
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        output.println(message_type + "|" + sb);
    }
    
    public synchronized void sendMessage(int message_type, String[] params) {
        StringBuilder sb = new StringBuilder();
        if (params != null) {
            for (String p : params) {
                sb.append(p).append(":");
            }
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        output.println(message_type + "|" + sb);
    }

    private class ClientThread extends Thread {

        @Override
        public void run() {
            String line;
            try {
                while ((line = input.readLine()) != null) {
                    System.out.println("got line: " + line);
                    String[] a = line.split("\\|");
                    int type = Integer.parseInt(a[0]);
                    String[] arg;
                    if (a.length > 1) {
                        arg = a[1].split(":");
                    } else {
                        arg = new String[]{};
                    }

                    processListeners(type, arg);
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            try {
                input.close();
                output.close();
                s.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
